package com.huatai.user.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huatai.common.entity.UserInfo;
import com.huatai.common.error.exception.ServiceException;
import com.huatai.common.util.AuthUtil;
import com.huatai.common.util.ForestNodeMerger;
import com.huatai.user.entity.Role;
import com.huatai.user.entity.RolePermission;
import com.huatai.user.mapper.RoleMapper;
import com.huatai.user.service.RolePermissionService;
import com.huatai.user.service.RoleService;
import com.huatai.user.vo.PermissionVo;
import com.huatai.user.vo.RolePermissuinParamVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: ht-system
 * @description: 角色
 * @author: songxiude
 * @create: 2023-02-09 13:20
 **/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
	@Autowired
	private RolePermissionService rolePermissionService;

	@Lazy
	@Autowired
	private RoleServiceImpl roleService;

	/**
	 * 保存修改角色
	 *
	 * @param role
	 * @return
	 */
	public boolean saveRole(Role role) {
		UserInfo user = AuthUtil.getUser();
		role.setUpdateUserid(user.getUserId());
		//如果不传主键id视为新增
		if (role.getRoleId().longValue() <= 0 || role.getRoleId() == null) {
			role.setRoleId(IdWorker.getId());
			role.setCreateUserid(user.getUserId());
		}
		return saveOrUpdate(role);
	}

	/**
	 * 获取角色列表
	 *
	 * @return
	 */
	public List<Role> getRoleList() {
		List<Role> roles = baseMapper.selectList(Wrappers.<Role>lambdaQuery()
			.eq(Role::getStatus, 0)
			.orderByAsc(Role::getRoleSort));
		return Optional.ofNullable(roles).orElse(Collections.emptyList());
	}

	/**
	 * 删除角色
	 *
	 * @param roleId
	 * @return
	 */
	@Transactional(rollbackFor = {Exception.class})
	public boolean delRole(Long roleId) {
		//判断如果是超级管理员组不允许删除
		if(roleId.longValue()==1){
			throw new ServiceException("超级管理员组不允许删除");
		}
		int relnumber = baseMapper.deleteById(roleId);
		//如果删除成功删除该角色所拥有资源权限
		if (relnumber > 0) {
			//异步删除
			roleService.delRolePermissions(roleId);
			return true;
		}
		return false;
	}

	/**
	 * 角色配置资源权限
	 *
	 * @param paramVo
	 * @return
	 */
	@Transactional(rollbackFor = {Exception.class})
	public boolean rolePermissionEdit(RolePermissuinParamVo paramVo) {
		//先删除该角色之前资源权限
		rolePermissionService.remove(Wrappers.<RolePermission>lambdaQuery().eq(RolePermission::getRoleId, paramVo.getRoleId()));
		//组装新的角色资源权限并保存
		List<RolePermission> permissions = new ArrayList<>();
		paramVo.getPermissions().forEach(aLong -> {
			RolePermission rolePermission = new RolePermission();
			rolePermission.setRoleId(paramVo.getRoleId());
			rolePermission.setPermissionId(aLong);
			permissions.add(rolePermission);
		});
		return rolePermissionService.saveBatch(permissions);
	}

	/**
	 * 获取角色资源权限标注列表（前端回显使用）
	 * @param roleId
	 * @return
	 */
	public List<PermissionVo> getRolePermissions(Long roleId) {
		//先获取该角色原有资源权限
		List<Long> perIds = baseMapper.getRolePerIds(roleId);
		String persStr = perIds.stream().map(aLong -> aLong + "").collect(Collectors.joining(","));
		//再获取全部资源权限标注选中状态递归返回
		List<PermissionVo> permissions = baseMapper.getRolePermissions(persStr);
		List<PermissionVo> permissionChs = getTrees(0L, permissions);
//		List<PermissionVo> permissionChs = baseMapper.getPermissionChs(persStr, 0L);
		return permissionChs;
	}

	/**
	 * 递归获取子级列表
	 *
	 * @param id
	 * @param trees
	 * @return
	 */
	private List<PermissionVo> getTrees(Long id, List<PermissionVo> trees) {
		List<PermissionVo> list = new ArrayList<>();
		for (PermissionVo tree : trees) {
			if (tree.getParentId().longValue() == id.longValue()) {
				tree.setChildren(getTrees(tree.getId(), trees));
				list.add(tree);
			}
		}
		return list;
	}

	/**
	 * 异步删除角色拥有资源权限
	 *
	 * @param roleId
	 */
	@Async("threadPoolExecutor")
	public void delRolePermissions(Long roleId) {
		rolePermissionService.remove(Wrappers.<RolePermission>lambdaQuery().eq(RolePermission::getRoleId, roleId));
	}
}
